﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Threading;

namespace System.Controls.Extensions
{
  [DebuggerStepThrough]
  public static class DispatcherEx
  {
    private const DispatcherPriority DEFAULT_PRIORITY = DispatcherPriority.Background;

    public static void ProcessMessages( this Dispatcher dispatcher )
    {
      var dop = dispatcher.BeginInvoke( (Action) delegate { }, DispatcherPriority.Background );
      dop.Wait();
    }

    public static void Wait( this Dispatcher dispatcher, long milliSeconds = 5 )
    {
      var sw = Stopwatch.StartNew();

      do
      {
        Thread.SpinWait( 3 );
        dispatcher.ProcessMessages();

      } while ( sw.ElapsedMilliseconds < milliSeconds );

    }

    public static void InvokeIfRequired( this Dispatcher dispatcher, Action action, DispatcherPriority priority = DEFAULT_PRIORITY )
    {
      if ( dispatcher.CheckAccess() )
        action();
      else
        dispatcher.Invoke( priority, action );
    }

    public static void InvokeIfRequired<T>( this Dispatcher dispatcher, Action<T> action, T parameter, DispatcherPriority priority = DEFAULT_PRIORITY )
    {
      if ( dispatcher.CheckAccess() )
        action( parameter );
      else
        dispatcher.Invoke( priority, action, parameter );
    }

    public static void InvokeBackground( this Dispatcher dispatcher, Action action )
    {
      dispatcher.BeginInvoke( action, DispatcherPriority.Background );
    }

    public static void InvokeBackground<T>( this Dispatcher dispatcher, Action<T> action, T parameter )
    {
      dispatcher.BeginInvoke( action, DispatcherPriority.Background, parameter );
    }

  }

}
